#pragma once
#include "enum.h"
#include <string>
#include <string_view>
#include <unordered_map>

struct Token {
  enum class TokenType {
    UNKNOWN,
    // 数据类型
    NUM,           // 数字
    STRING,        // 字符串
    ID,            // 变量名
    INTERPOLATION, // 内嵌表达式

    // 关键字(系统保留字)
    VAR,      //'var'
    FUN,      //'fun'
    IF,       //'if'
    ELSE,     //'else'
    TTRUE,    //'true'
    TFALSE,   //'false'
    WHILE,    //'while'
    FOR,      //'for'
    BREAK,    //'break'
    CONTINUE, //'continue'
    RETURN,   //'return'
    TNULL,    //'null'

    // 以下是关于类和模块导入的token
    CLASS,  //'class'
    THIS,   //'this'
    STATIC, //'static'
    IS,     // 'is'
    SUPER,  //'super'
    IMPORT, //'import'

    // 分隔符
    COMMA,         //','
    COLON,         //':'
    LEFT_PAREN,    //'('
    RIGHT_PAREN,   //')'
    LEFT_BRACKET,  //'['
    RIGHT_BRACKET, //']'
    LEFT_BRACE,    //'{'
    RIGHT_BRACE,   //'}'
    DOT,           //'.'
    DOT_DOT,       //'..'

    // 简单双目运算符
    ADD, //'+'
    SUB, //'-'
    MUL, //'*'
    DIV, //'/'
    MOD, //'%'

    // 赋值运算符
    ASSIGN, //'='

    // 位运算符
    BIT_AND,         //'&'
    BIT_OR,          //'|'
    BIT_NOT,         //'~'
    BIT_SHIFT_RIGHT, //'>>'
    BIT_SHIFT_LEFT,  //'<<'

    // 逻辑运算符
    LOGIC_AND, //'&&'
    LOGIC_OR,  //'||'
    LOGIC_NOT, //'!'

    // 关系操作符
    EQUAL,        //'=='
    NOT_EQUAL,    //'!='
    GREATE,       //'>'
    GREATE_EQUAL, //'>='
    LESS,         //'<'
    LESS_EQUAL,   //'<='

    QUESTION, //'?'

    // 文件结束标记,仅词法分析时使用
    TEOF //'EOF'
  };

  TokenType type{TokenType::UNKNOWN};
  std::string_view content{""};
  std::size_t lineno{1};
};

// 关键字查找表
inline std::unordered_map<std::string_view, Token::TokenType> keywordsToken{
    {"var", Token::TokenType::VAR},       {"fun", Token::TokenType::FUN},
    {"if", Token::TokenType::IF},         {"else", Token::TokenType::ELSE},
    {"true", Token::TokenType::TTRUE},    {"false",Token::TokenType::TFALSE},
    {"while", Token::TokenType::WHILE},   {"for", Token::TokenType::FOR},
    {"break", Token::TokenType::BREAK},   {"continue", Token::TokenType::CONTINUE},
    {"return", Token::TokenType::RETURN}, {"null", Token::TokenType::TNULL},
    {"class", Token::TokenType::CLASS},   {"is", Token::TokenType::IS},
    {"static", Token::TokenType::STATIC}, {"this", Token::TokenType::THIS},
    {"super", Token::TokenType::SUPER},   {"import", Token::TokenType::IMPORT},
    {"", Token::TokenType::UNKNOWN}};